package bank

import (
	"LogisticsPort/model"
	"LogisticsPort/sql"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

func statementAdd(c *gin.Context) {
	sql.HttpHandle(sql.ADD, c, func(db *gorm.DB) (*gorm.DB, interface{}) {
		var bean model.BankStatement
		if err := c.Bind(&bean); err != nil {
			fmt.Println(err)
			db.Error = errors.New(sql.ErrorParams)
			return db, nil
		}
		var tx = db.Begin()
		//1、创建对账单
		if err := tx.Create(&bean).Error; err != nil {
			tx.Error = errors.New(sql.ErrorService + "1")
			tx.Callback()
			return tx, nil
		}

		//2、修改银行流水可结算余额
		if err := statementChanges(tx, bean.BankFlowId, bean.Money, false); err != nil {
			return tx, nil
		}

		tx.Commit()
		return db, bean
	})
}

func statementUpdates(c *gin.Context) {
	sql.HttpHandle(sql.ADD, c, func(db *gorm.DB) (*gorm.DB, interface{}) {
		var bean model.BankStatement
		if err := c.Bind(&bean); err != nil {
			fmt.Println(err)
			db.Error = errors.New(sql.ErrorParams)
			return db, nil
		}
		var tx = db.Begin()

		//1、获取被修改的对账单
		var oldBean model.BankStatement
		if err := tx.Where("id = ?", oldBean.ID).First(&oldBean).Error; err != nil {
			tx.Error = errors.New(sql.ErrorParams)
			tx.Callback()
			return tx, nil
		}

		//2、根据对账单还原银行流水
		if err := statementChanges(tx, oldBean.BankFlowId, oldBean.Money, true); err != nil {
			return tx, nil
		}

		//3、修改对账单
		if err := tx.Updates(&bean).Error; err != nil {
			tx.Error = errors.New(sql.ErrorParams)
			tx.Callback()
			return tx, nil
		}

		//3、修改银行流水金额
		if err := statementChanges(tx, bean.BankFlowId, bean.Money, false); err != nil {
			return tx, nil
		}

		tx.Commit()
		return db, bean
	})
}

func statementList(c *gin.Context) {
	sql.HttpList(c, &[]model.BankStatement{}, func(db *gorm.DB) *gorm.DB {
		functionId := c.Query("functionId")
		function := c.Query("function")
		if function != "" && functionId != "" {
			db = db.Where("bank_statement.function_id = ? AND bank_statement.function = ?", functionId, function)
		}
		if accountId := c.Query("accountId"); accountId != "" {
			db = db.Where("bank_statement.account_id = ?", accountId)
		}
		if bankFlowId := c.Query("bankFlowId"); bankFlowId != "" {
			db = db.Where("bank_statement.bank_flow_id = ?", bankFlowId)
		}
		db = db.
			Select("bank_statement.*,bank_account.bank,bank_account.account_name,bank_account.card_number,bank_flow.date").
			Joins("left join bank_account ON bank_statement.account_id = bank_account.id").
			Joins("left join bank_flow ON bank_statement.bank_flow_id = bank_flow.id")
		db = db.Order("date DESC")
		return db
	})
}

func statementData(c *gin.Context) {
	sql.HttpHandle(sql.GET, c, func(db *gorm.DB) (*gorm.DB, interface{}) {
		var statementBean model.BankStatement
		id := c.Query("id")
		tx := db.Begin()
		if err := tx.Where("id = ?", id).First(&statementBean); err != nil {
			tx.Error = errors.New(sql.ErrorService)
			tx.Callback()
			return tx, nil
		}
		if statementBean.Function == "一般费用" || statementBean.Function == "其他支出" {

		} else if statementBean.Function == "采购" {
			var purchaseBean model.PurchaseProduct
			tx.Where("id = ?", statementBean.FunctionId).Find(&purchaseBean)
		}
		tx.Commit()
		return db, nil
	})
}

func statementDelete(c *gin.Context) {
	sql.HttpHandle(sql.ADD, c, func(db *gorm.DB) (*gorm.DB, interface{}) {
		var bean model.BankStatement
		id := c.Query("id")
		tx := db.Begin()

		//1、获取被删除掉数据
		if err := tx.Where("id = ?", id).First(&bean).Error; err != nil {
			tx.Error = errors.New(sql.ErrorService)
			tx.Callback()
			return tx, nil
		}

		//2、删除数据
		if err := tx.Delete(&bean).Error; err != nil {
			tx.Error = errors.New(sql.ErrorService)
			tx.Callback()
			return tx, nil
		}

		//3、根据删除的数据修改金额
		if err := statementChanges(tx, bean.BankFlowId, bean.Money, true); err != nil {
			return tx, nil
		}
		tx.Commit()
		return db, nil
	})

}

/*
*
*银行账户余额变动
 */
func statementChanges(tx *gorm.DB, accountId int, money float64, isAdd bool) error {

	var bankFlow model.BankFlow
	if err := tx.First(&bankFlow, accountId).Error; err != nil {
		tx.Error = errors.New(sql.ErrorService)
		tx.Callback()
		return err
	}

	if isAdd {
		bankFlow.Balance = bankFlow.Balance.Add(decimal.NewFromFloat(money))
	} else {
		bankFlow.Balance = bankFlow.Balance.Sub(decimal.NewFromFloat(money))
	}
	if err := tx.Save(&bankFlow).Error; err != nil {
		tx.Error = errors.New(sql.ErrorService)
		tx.Callback()
		return err
	}

	return nil
}
